package com.chushouya.order.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * 订单服务RabbitMQ配置类
 * 可以通过配置 spring.rabbitmq.enabled=false 来禁用RabbitMQ
 */
@Configuration
@ConditionalOnProperty(prefix = "spring.rabbitmq", name = "enabled", havingValue = "true", matchIfMissing = true)
public class OrderRabbitMQConfig {

    private static final Logger logger = LoggerFactory.getLogger(OrderRabbitMQConfig.class);

    // 订单处理队列常量
    public static final String ORDER_QUEUE = "order.queue";
    public static final String ORDER_EXCHANGE = "order.exchange";
    public static final String ORDER_ROUTING_KEY = "order.routing.key";
    
    // 订单状态变更队列常量
    public static final String ORDER_STATUS_QUEUE = "order.status.queue";
    public static final String ORDER_STATUS_EXCHANGE = "order.status.exchange";
    public static final String ORDER_STATUS_ROUTING_KEY = "order.status.routing.key";
    
    // 订单超时队列常量
    public static final String ORDER_TIMEOUT_QUEUE = "order.timeout.queue";
    public static final String ORDER_TIMEOUT_EXCHANGE = "order.timeout.exchange";
    public static final String ORDER_TIMEOUT_ROUTING_KEY = "order.timeout.routing.key";
    
    // 订单超时关闭延时队列常量
    public static final String ORDER_TIMEOUT_CLOSE_DELAY_QUEUE = "order.timeout.close.delay.queue";
    public static final String ORDER_TIMEOUT_CLOSE_DELAY_EXCHANGE = "order.timeout.close.delay.exchange";
    public static final String ORDER_TIMEOUT_CLOSE_DELAY_ROUTING_KEY = "order.timeout.close.delay.routing.key";
    
    // 订单超时关闭实际处理队列常量
    public static final String ORDER_TIMEOUT_CLOSE_QUEUE = "order.timeout.close.queue";
    public static final String ORDER_TIMEOUT_CLOSE_EXCHANGE = "order.timeout.close.exchange";
    public static final String ORDER_TIMEOUT_CLOSE_ROUTING_KEY = "order.timeout.close.routing.key";
    
    // 订单自动确认收货延时队列常量
    public static final String ORDER_AUTO_CONFIRM_DELAY_QUEUE = "order.auto.confirm.delay.queue";
    public static final String ORDER_AUTO_CONFIRM_DELAY_EXCHANGE = "order.auto.confirm.delay.exchange";
    public static final String ORDER_AUTO_CONFIRM_DELAY_ROUTING_KEY = "order.auto.confirm.delay.routing.key";
    
    // 订单自动确认收货实际处理队列常量
    public static final String ORDER_AUTO_CONFIRM_QUEUE = "order.auto.confirm.queue";
    public static final String ORDER_AUTO_CONFIRM_EXCHANGE = "order.auto.confirm.exchange";
    public static final String ORDER_AUTO_CONFIRM_ROUTING_KEY = "order.auto.confirm.routing.key";
    
    // 订单死信队列常量
    public static final String ORDER_DEAD_LETTER_EXCHANGE = "order.dead.letter.exchange";
    public static final String ORDER_DEAD_LETTER_QUEUE = "order.dead.letter.queue";
    public static final String ORDER_DEAD_LETTER_ROUTING_KEY = "order.dead.letter.routing.key";
    
    // 支付宝小程序订单创建队列常量
    public static final String OPEN_MINI_ORDER_CREATE_QUEUE = "open.mini.order.create.queue";
    public static final String OPEN_MINI_ORDER_CREATE_EXCHANGE = "open.mini.order.create.exchange";
    public static final String OPEN_MINI_ORDER_CREATE_ROUTING_KEY = "open.mini.order.create.routing.key";
    
    // 支付宝小程序订单报价队列常量
    public static final String OPEN_MINI_ORDER_QUOTE_QUEUE = "open.mini.order.quote.queue";
    public static final String OPEN_MINI_ORDER_QUOTE_EXCHANGE = "open.mini.order.quote.exchange";
    public static final String OPEN_MINI_ORDER_QUOTE_ROUTING_KEY = "open.mini.order.quote.routing.key";
    
    // 支付宝小程序订单确认队列常量
    public static final String OPEN_MINI_ORDER_CONFIRM_QUEUE = "open.mini.order.confirm.queue";
    public static final String OPEN_MINI_ORDER_CONFIRM_EXCHANGE = "open.mini.order.confirm.exchange";
    public static final String OPEN_MINI_ORDER_CONFIRM_ROUTING_KEY = "open.mini.order.confirm.routing.key";
    
    // 支付宝小程序订单发货队列常量
    public static final String OPEN_MINI_ORDER_DELIVERY_SEND_QUEUE = "open.mini.order.delivery.send.queue";
    public static final String OPEN_MINI_ORDER_DELIVERY_SEND_EXCHANGE = "open.mini.order.delivery.send.exchange";
    public static final String OPEN_MINI_ORDER_DELIVERY_SEND_ROUTING_KEY = "open.mini.order.delivery.send.routing.key";
    
    // 支付宝小程序订单送达队列常量
    public static final String OPEN_MINI_ORDER_DELIVERY_DELIVERY_QUEUE = "open.mini.order.delivery.delivery.queue";
    public static final String OPEN_MINI_ORDER_DELIVERY_DELIVERY_EXCHANGE = "open.mini.order.delivery.delivery.exchange";
    public static final String OPEN_MINI_ORDER_DELIVERY_DELIVERY_ROUTING_KEY = "open.mini.order.delivery.delivery.routing.key";
    
    // 门店订单超时关闭队列常量
    public static final String STORE_ORDER_TIMEOUT_CLOSE_QUEUE = "store.order.timeout.close.queue";
    public static final String STORE_ORDER_TIMEOUT_CLOSE_EXCHANGE = "store.order.timeout.close.exchange";
    public static final String STORE_ORDER_TIMEOUT_CLOSE_ROUTING_KEY = "store.order.timeout.close.routing.key";
    
    // 门店订单超时关闭延时队列常量
    public static final String STORE_ORDER_TIMEOUT_CLOSE_DELAY_QUEUE = "store.order.timeout.close.delay.queue";
    public static final String STORE_ORDER_TIMEOUT_CLOSE_DELAY_EXCHANGE = "store.order.timeout.close.delay.exchange";
    public static final String STORE_ORDER_TIMEOUT_CLOSE_DELAY_ROUTING_KEY = "store.order.timeout.close.delay.routing.key";

    // 定义订单处理队列
    @Bean
    public Queue orderQueue() {
        return QueueBuilder.durable(ORDER_QUEUE).build();
    }

    // 定义订单交换机
    @Bean
    public DirectExchange orderExchange() {
        return ExchangeBuilder.directExchange(ORDER_EXCHANGE).durable(true).build();
    }

    // 将订单队列与交换机绑定
    @Bean
    public Binding orderBinding() {
        return BindingBuilder.bind(orderQueue()).to(orderExchange()).with(ORDER_ROUTING_KEY);
    }
    
    // 定义订单状态变更队列
    @Bean
    public Queue orderStatusQueue() {
        return QueueBuilder.durable(ORDER_STATUS_QUEUE).build();
    }
    
    // 定义订单状态变更交换机
    @Bean
    public DirectExchange orderStatusExchange() {
        return ExchangeBuilder.directExchange(ORDER_STATUS_EXCHANGE).durable(true).build();
    }
    
    // 将订单状态变更队列与交换机绑定
    @Bean
    public Binding orderStatusBinding() {
        return BindingBuilder.bind(orderStatusQueue()).to(orderStatusExchange()).with(ORDER_STATUS_ROUTING_KEY);
    }
    
    // 定义订单死信交换机
    @Bean
    public DirectExchange orderDeadLetterExchange() {
        return ExchangeBuilder.directExchange(ORDER_DEAD_LETTER_EXCHANGE).durable(true).build();
    }
    
    // 定义订单死信队列
    @Bean
    public Queue orderDeadLetterQueue() {
        return QueueBuilder.durable(ORDER_DEAD_LETTER_QUEUE).build();
    }
    
    // 将订单死信队列绑定到死信交换机
    @Bean
    public Binding orderDeadLetterBinding() {
        return BindingBuilder.bind(orderDeadLetterQueue()).to(orderDeadLetterExchange()).with(ORDER_DEAD_LETTER_ROUTING_KEY);
    }
    
    // 定义订单超时队列，到期后消息会转发到死信交换机
    @Bean
    public Queue orderTimeoutQueue() {
        Map<String, Object> args = new HashMap<>(3);
        // 设置死信交换机
        args.put("x-dead-letter-exchange", ORDER_DEAD_LETTER_EXCHANGE);
        // 设置死信路由键
        args.put("x-dead-letter-routing-key", ORDER_DEAD_LETTER_ROUTING_KEY);
        // 不设置默认过期时间，通过消息属性单独设置
        return QueueBuilder.durable(ORDER_TIMEOUT_QUEUE).withArguments(args).build();
    }
    
    // 定义订单超时交换机
    @Bean
    public DirectExchange orderTimeoutExchange() {
        return ExchangeBuilder.directExchange(ORDER_TIMEOUT_EXCHANGE).durable(true).build();
    }
    
    // 将订单超时队列绑定到超时交换机
    @Bean
    public Binding orderTimeoutBinding() {
        return BindingBuilder.bind(orderTimeoutQueue()).to(orderTimeoutExchange()).with(ORDER_TIMEOUT_ROUTING_KEY);
    }
    
    // 定义订单超时关闭实际处理队列
    @Bean
    public Queue orderTimeoutCloseQueue() {
        return QueueBuilder.durable(ORDER_TIMEOUT_CLOSE_QUEUE).build();
    }
    
    // 定义订单超时关闭交换机
    @Bean
    public DirectExchange orderTimeoutCloseExchange() {
        return ExchangeBuilder.directExchange(ORDER_TIMEOUT_CLOSE_EXCHANGE).durable(true).build();
    }
    
    // 将订单超时关闭队列绑定到交换机
    @Bean
    public Binding orderTimeoutCloseBinding() {
        return BindingBuilder.bind(orderTimeoutCloseQueue()).to(orderTimeoutCloseExchange()).with(ORDER_TIMEOUT_CLOSE_ROUTING_KEY);
    }
    
    // 定义订单超时关闭延时队列，过期后转发到实际处理队列
    @Bean
    public Queue orderTimeoutCloseDelayQueue() {
        Map<String, Object> args = new HashMap<>(3);
        // 设置死信交换机
        args.put("x-dead-letter-exchange", ORDER_TIMEOUT_CLOSE_EXCHANGE);
        // 设置死信路由键
        args.put("x-dead-letter-routing-key", ORDER_TIMEOUT_CLOSE_ROUTING_KEY);
        // 不设置默认过期时间，通过消息属性单独设置
        return QueueBuilder.durable(ORDER_TIMEOUT_CLOSE_DELAY_QUEUE).withArguments(args).build();
    }
    
    // 定义订单超时关闭延时交换机
    @Bean
    public DirectExchange orderTimeoutCloseDelayExchange() {
        return ExchangeBuilder.directExchange(ORDER_TIMEOUT_CLOSE_DELAY_EXCHANGE).durable(true).build();
    }
    
    // 将订单超时关闭延时队列绑定到延时交换机
    @Bean
    public Binding orderTimeoutCloseDelayBinding() {
        return BindingBuilder.bind(orderTimeoutCloseDelayQueue()).to(orderTimeoutCloseDelayExchange()).with(ORDER_TIMEOUT_CLOSE_DELAY_ROUTING_KEY);
    }
    
    // 定义订单自动确认收货实际处理队列
    @Bean
    public Queue orderAutoConfirmQueue() {
        return QueueBuilder.durable(ORDER_AUTO_CONFIRM_QUEUE).build();
    }
    
    // 定义订单自动确认收货交换机
    @Bean
    public DirectExchange orderAutoConfirmExchange() {
        return ExchangeBuilder.directExchange(ORDER_AUTO_CONFIRM_EXCHANGE).durable(true).build();
    }
    
    // 将订单自动确认收货队列绑定到交换机
    @Bean
    public Binding orderAutoConfirmBinding() {
        return BindingBuilder.bind(orderAutoConfirmQueue()).to(orderAutoConfirmExchange()).with(ORDER_AUTO_CONFIRM_ROUTING_KEY);
    }
    
    // 定义订单自动确认收货延时队列，过期后转发到实际处理队列
    @Bean
    public Queue orderAutoConfirmDelayQueue() {
        Map<String, Object> args = new HashMap<>(3);
        // 设置死信交换机
        args.put("x-dead-letter-exchange", ORDER_AUTO_CONFIRM_EXCHANGE);
        // 设置死信路由键
        args.put("x-dead-letter-routing-key", ORDER_AUTO_CONFIRM_ROUTING_KEY);
        // 不设置默认过期时间，通过消息属性单独设置
        return QueueBuilder.durable(ORDER_AUTO_CONFIRM_DELAY_QUEUE).withArguments(args).build();
    }
    
    // 定义订单自动确认收货延时交换机
    @Bean
    public DirectExchange orderAutoConfirmDelayExchange() {
        return ExchangeBuilder.directExchange(ORDER_AUTO_CONFIRM_DELAY_EXCHANGE).durable(true).build();
    }
    
    // 将订单自动确认收货延时队列绑定到延时交换机
    @Bean
    public Binding orderAutoConfirmDelayBinding() {
        return BindingBuilder.bind(orderAutoConfirmDelayQueue()).to(orderAutoConfirmDelayExchange()).with(ORDER_AUTO_CONFIRM_DELAY_ROUTING_KEY);
    }

    // 消息转换器，使用JSON格式
    @Bean
    public MessageConverter orderJsonMessageConverter() {
        Jackson2JsonMessageConverter converter = new Jackson2JsonMessageConverter();
        return converter;
    }
    
    // 定义支付宝小程序订单创建队列
    @Bean
    public Queue openMiniOrderCreateQueue() {
        return QueueBuilder.durable(OPEN_MINI_ORDER_CREATE_QUEUE).build();
    }
    
    // 定义支付宝小程序订单创建交换机
    @Bean
    public DirectExchange openMiniOrderCreateExchange() {
        return ExchangeBuilder.directExchange(OPEN_MINI_ORDER_CREATE_EXCHANGE).durable(true).build();
    }
    
    // 将支付宝小程序订单创建队列与交换机绑定
    @Bean
    public Binding openMiniOrderCreateBinding() {
        return BindingBuilder.bind(openMiniOrderCreateQueue()).to(openMiniOrderCreateExchange()).with(OPEN_MINI_ORDER_CREATE_ROUTING_KEY);
    }
    
    // 定义支付宝小程序订单报价队列
    @Bean
    public Queue openMiniOrderQuoteQueue() {
        return QueueBuilder.durable(OPEN_MINI_ORDER_QUOTE_QUEUE).build();
    }
    
    // 定义支付宝小程序订单报价交换机
    @Bean
    public DirectExchange openMiniOrderQuoteExchange() {
        return ExchangeBuilder.directExchange(OPEN_MINI_ORDER_QUOTE_EXCHANGE).durable(true).build();
    }
    
    // 将支付宝小程序订单报价队列与交换机绑定
    @Bean
    public Binding openMiniOrderQuoteBinding() {
        return BindingBuilder.bind(openMiniOrderQuoteQueue()).to(openMiniOrderQuoteExchange()).with(OPEN_MINI_ORDER_QUOTE_ROUTING_KEY);
    }
    
    // 定义支付宝小程序订单确认队列
    @Bean
    public Queue openMiniOrderConfirmQueue() {
        return QueueBuilder.durable(OPEN_MINI_ORDER_CONFIRM_QUEUE).build();
    }
    
    // 定义支付宝小程序订单确认交换机
    @Bean
    public DirectExchange openMiniOrderConfirmExchange() {
        return ExchangeBuilder.directExchange(OPEN_MINI_ORDER_CONFIRM_EXCHANGE).durable(true).build();
    }
    
    // 将支付宝小程序订单确认队列与交换机绑定
    @Bean
    public Binding openMiniOrderConfirmBinding() {
        return BindingBuilder.bind(openMiniOrderConfirmQueue()).to(openMiniOrderConfirmExchange()).with(OPEN_MINI_ORDER_CONFIRM_ROUTING_KEY);
    }
    
    // 定义支付宝小程序订单发货队列
    @Bean
    public Queue openMiniOrderDeliverySendQueue() {
        return QueueBuilder.durable(OPEN_MINI_ORDER_DELIVERY_SEND_QUEUE).build();
    }
    
    // 定义支付宝小程序订单发货交换机
    @Bean
    public DirectExchange openMiniOrderDeliverySendExchange() {
        return ExchangeBuilder.directExchange(OPEN_MINI_ORDER_DELIVERY_SEND_EXCHANGE).durable(true).build();
    }
    
    // 将支付宝小程序订单发货队列与交换机绑定
    @Bean
    public Binding openMiniOrderDeliverySendBinding() {
        return BindingBuilder.bind(openMiniOrderDeliverySendQueue()).to(openMiniOrderDeliverySendExchange()).with(OPEN_MINI_ORDER_DELIVERY_SEND_ROUTING_KEY);
    }
    
    // 定义支付宝小程序订单送达队列
    @Bean
    public Queue openMiniOrderDeliveryDeliveryQueue() {
        return QueueBuilder.durable(OPEN_MINI_ORDER_DELIVERY_DELIVERY_QUEUE).build();
    }
    
    // 定义支付宝小程序订单送达交换机
    @Bean
    public DirectExchange openMiniOrderDeliveryDeliveryExchange() {
        return ExchangeBuilder.directExchange(OPEN_MINI_ORDER_DELIVERY_DELIVERY_EXCHANGE).durable(true).build();
    }
    
    // 将支付宝小程序订单送达队列与交换机绑定
    @Bean
    public Binding openMiniOrderDeliveryDeliveryBinding() {
        return BindingBuilder.bind(openMiniOrderDeliveryDeliveryQueue()).to(openMiniOrderDeliveryDeliveryExchange()).with(OPEN_MINI_ORDER_DELIVERY_DELIVERY_ROUTING_KEY);
    }
    
    // 定义门店订单超时关闭实际处理队列
    @Bean
    public Queue storeOrderTimeoutCloseQueue() {
        return QueueBuilder.durable(STORE_ORDER_TIMEOUT_CLOSE_QUEUE).build();
    }
    
    // 定义门店订单超时关闭交换机
    @Bean
    public DirectExchange storeOrderTimeoutCloseExchange() {
        return ExchangeBuilder.directExchange(STORE_ORDER_TIMEOUT_CLOSE_EXCHANGE).durable(true).build();
    }
    
    // 将门店订单超时关闭队列绑定到交换机
    @Bean
    public Binding storeOrderTimeoutCloseBinding() {
        return BindingBuilder.bind(storeOrderTimeoutCloseQueue()).to(storeOrderTimeoutCloseExchange()).with(STORE_ORDER_TIMEOUT_CLOSE_ROUTING_KEY);
    }
    
    // 定义门店订单超时关闭延时队列，过期后转发到实际处理队列
    @Bean
    public Queue storeOrderTimeoutCloseDelayQueue() {
        Map<String, Object> args = new HashMap<>(3);
        // 设置死信交换机
        args.put("x-dead-letter-exchange", STORE_ORDER_TIMEOUT_CLOSE_EXCHANGE);
        // 设置死信路由键
        args.put("x-dead-letter-routing-key", STORE_ORDER_TIMEOUT_CLOSE_ROUTING_KEY);
        // 不设置默认过期时间，通过消息属性单独设置
        return QueueBuilder.durable(STORE_ORDER_TIMEOUT_CLOSE_DELAY_QUEUE).withArguments(args).build();
    }
    
    // 定义门店订单超时关闭延时交换机
    @Bean
    public DirectExchange storeOrderTimeoutCloseDelayExchange() {
        return ExchangeBuilder.directExchange(STORE_ORDER_TIMEOUT_CLOSE_DELAY_EXCHANGE).durable(true).build();
    }
    
    // 将门店订单超时关闭延时队列绑定到延时交换机
    @Bean
    public Binding storeOrderTimeoutCloseDelayBinding() {
        return BindingBuilder.bind(storeOrderTimeoutCloseDelayQueue()).to(storeOrderTimeoutCloseDelayExchange()).with(STORE_ORDER_TIMEOUT_CLOSE_DELAY_ROUTING_KEY);
    }
    
    // 配置RabbitTemplate
    @Bean
    public RabbitTemplate orderRabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(orderJsonMessageConverter());
        
        // 消息发送确认回调
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (ack) {
                logger.debug("订单消息发送成功，correlationData={}", correlationData);
            } else {
                logger.error("订单消息发送失败，correlationData={}, cause={}", correlationData, cause);
            }
        });
        
        // 消息发送失败返回回调
        rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
            logger.error("订单消息路由失败：exchange={}, routingKey={}, replyCode={}, replyText={}, message={}", 
                    exchange, routingKey, replyCode, replyText, message);
        });
        
        logger.info("订单RabbitMQ配置初始化完成");
        return rabbitTemplate;
    }
}
